
#include "itkImage.h"
#include "itkImageFileWriter.h"

#include <iostream>
#include <itkGDCMImageIO.h>
#include <itkImageFileReader.h>
#include <string>

int
main(int argc, char * argv[])
{
    if (argc < 3)
    {
        std::cerr << "Usage: " << std::endl;
        std::cerr << argv[0] << "InputImage DicomImage\n";
        return EXIT_FAILURE;
    }


    std::string inputFilename = argv[1];
    std::string outputFilename = argv[2];

    // dcm define
    using ImageIOType = itk::GDCMImageIO;
    ImageIOType::Pointer gdcmImageIO = ImageIOType::New();

    // input/output define
    using PixelType = signed short;
    constexpr unsigned int InputDimension = 2;
    using ImageType = itk::Image<PixelType, InputDimension>;
    //using ImageType = itk::Image<PixelType, InputDimension>;
    using ReaderType = itk::ImageFileReader<ImageType>;
    using WriterType = itk::ImageFileWriter<ImageType>;

    // iterator difine
    using ConstIteratorType = itk::ImageRegionConstIterator<ImageType>;
    using IteratorType = itk::ImageRegionIterator<ImageType>;

    // input
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(inputFilename);
    reader->SetImageIO(gdcmImageIO);

    try {
        reader->Update();
    }
    catch (const itk::ExceptionObject & e) {
        std::cerr << "exception in file reader " << std::endl;
        std::cerr << e << std::endl;
        return EXIT_FAILURE;
    }


    ImageType::RegionType outputRegion = reader->GetOutput()->GetRequestedRegion();
    ImageType::Pointer outputImage = ImageType::New();
    outputImage->SetRegions(outputRegion);
    const ImageType::SpacingType & spacing = reader->GetOutput()->GetSpacing();
    const ImageType::PointType & inputOrigin = reader->GetOutput()->GetOrigin();
    double                       outputOrigin[InputDimension];
    for (unsigned int i = 0; i < InputDimension; i++)
    {
        outputOrigin[i] = inputOrigin[i];
    }
    outputImage->SetSpacing(spacing);
    outputImage->SetOrigin(outputOrigin);
    outputImage->Allocate();


    ConstIteratorType inputIt(reader->GetOutput(), reader->GetOutput()->GetRequestedRegion());
    IteratorType outputIt(outputImage, outputRegion);

    inputIt.GoToBegin();
    outputIt.GoToBegin();

    while (!inputIt.IsAtEnd())
    {
        if (inputIt.Get() > 0) {
            outputIt.Set(12000);
        } else {
            outputIt.Set(0);
        }
        ++inputIt;
        ++outputIt;
    }

    WriterType::Pointer writer = WriterType::New();
    writer->SetFileName(outputFilename);
    writer->SetInput(outputImage);
    writer->SetImageIO(gdcmImageIO);
    try {
        writer->Update();
    }
    catch (const itk::ExceptionObject & err)
    {
        std::cerr << "ExceptionObject caught !" << std::endl;
        std::cerr << err << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
